program blaisemodo;

{$mode objfpc}{$H+}
{.$C+}

{$IFDEF SSE2_VMATH}
  {$CODEALIGN LOCALMIN=16}
  {$CODEALIGN VARMIN=16}
{$ENDIF}

uses
  Lx_Action       ,
  Lx_ChanMod      ,
  Lx_ChannelUI    ,
  Lx_Clip         ,
  Lx_Color        ,
  Lx_COM          ,
  Lx_Command      ,
  Lx_Deform       ,
  Lx_Draw         ,
  Lx_Envelope     ,
  Lx_File         ,
  Lx_Filter       ,
  Lx_Group        ,
  Lx_Handles      ,
  Lx_IDef         ,
  Lx_Image        ,
  Lx_ImageMon     ,
  Lx_IO           ,
  Lx_Item         ,
  Lx_Layer        ,
  Lx_Listener     ,
  Lx_Locator      ,
  Lx_Log          ,
  Lx_Mesh         ,
  Lx_Message      ,
  Lx_Notify       ,
  Lx_Package      ,
  Lx_Render       ,
  Lx_Result       ,
  Lx_RndJob       ,
  Lx_Server       ,
  Lx_Tableau      ,
  Lx_Value        ,
  Lx_Vector       ,
  Lx_VMath        ,
  Lx_Volume       ,
  Lx_Particle     ,
  Lx_Persist      ,
  Lx_PreviewSocket,
  Lx_RayCast      ,
  Lx_Schematic    ,
  Lx_Scripts      ,
  Lx_Select       ,
  Lx_SelTypes     ,
  Lx_Shade        ,
  Lx_Shdr         ,
  Lx_StdDialog    ,
  Lx_Surface      ,
  Lx_Thread       ,
  Lx_Tool         ,
  Lx_ToolUI       ,
  Lx_TriSurf      ,
  Lx_Undo         ,
  Lx_VModel       ,

  Math, EpikTimer, sysutils, windows;

// Tests & benchmarks

const
  TestIter = 1000000;
  Average  = 10;

var
  A , B , R , S : LXtFVector;
  A4, B4, R4    : array [0..3] of Single;
  X             : Single;
  C             : Boolean;

  L             : Byte;

  Timer         : TEpikTimer;
  ElapsedAvg    : Double;
  I, J          : UInt32;

begin
  Timer := TEpikTimer.Create(nil);

  with TVMathSSE2 do
  begin
    LXx_VSET3 (A, 1, 2, 3);
    LXx_VSET3 (B, 4, 5, 6);

    LXx_V4SET4(A4, 1, 2, 3, 4);
    LXx_V4SET4(B4, 5, 6, 7, 8);
  end;

  WriteLn('Doing ', TestIter, ' iterations ', 'with ', Average, ' averaged results ...'  );

  SetPriorityClass(GetCurrentProcess(), REALTIME_PRIORITY_CLASS);

  ElapsedAvg := 0;

  for J := 1 to Average do
  begin
    Timer.Start;

    for I := 1 to TestIter do
      //X :=
      TVMathSSE2.LXx_VCPY(A, B);

    Timer.Stop;

    ElapsedAvg := ElapsedAvg + Timer.Elapsed;

    Timer.Clear;
  end;

  WriteLn('SSE2 : ' + FloatToStrF((ElapsedAvg / Average) * 1000, ffFixed, 8, 4)
                    + ' ms');

  ElapsedAvg := 0;

  for J := 1 to Average do
  begin
    Timer.Start;

    for I := 1 to TestIter do
      //X :=
      TVMathF.LXx_VCPY(A, B);

    Timer.Stop;

    ElapsedAvg := ElapsedAvg + Timer.Elapsed;

    Timer.Clear;
  end;

  WriteLn('PSCL : ' + FloatToStrF((ElapsedAvg / Average) * 1000, ffFixed, 8, 4)
                    + ' ms');

  SetPriorityClass(GetCurrentProcess(), NORMAL_PRIORITY_CLASS);

  Timer.Free;
end.

